package com.dj.mingkong.portal.biz.service.system.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dj.mingkong.common.enums.StatusEnum;
import com.dj.mingkong.common.infrastructure.base.dto.context.UserInfoContext;
import com.dj.mingkong.common.infrastructure.eo.database.system.UserEo;
import com.dj.mingkong.common.infrastructure.eo.database.system.UserFansEo;
import com.dj.mingkong.common.microservice.UserContext;
import com.dj.mingkong.common.util.AssertUtils;
import com.dj.mingkong.common.util.SmartBeanCopy;
import com.dj.mingkong.portal.biz.controller.system.vo.request.UserFansAddVo;
import com.dj.mingkong.portal.biz.controller.system.vo.request.UserFansQueryVo;
import com.dj.mingkong.portal.biz.controller.system.vo.response.UserFansDetailVo;
import com.dj.mingkong.portal.biz.controller.system.vo.response.UserFansVo;
import com.dj.mingkong.portal.biz.core.base.context.UserContextHolder;
import com.dj.mingkong.portal.biz.repository.database.system.UserFansRepository;
import com.dj.mingkong.portal.biz.repository.database.system.UserRepository;
import com.dj.mingkong.portal.biz.service.system.UserFansService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.Optional;

/**
 * 用户粉丝服务实现
 *
 * @author zenglonghui
 * @date: 2022/8/25 11:34
 */
@Slf4j
@Service("userFansService")
public class UserFansServiceImpl implements UserFansService {
    @Resource
    private UserFansRepository userFansRepository;
    @Resource
    private UserContextHolder userContextHolder;
    @Resource
    private UserRepository userRepository;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void follow(UserFansAddVo addVo) {
        final UserEo userEo = userRepository.getById(addVo.getFollowUserId());
        AssertUtils.isNotNull(userEo, "followUserId invalid");
        final Optional<UserFansEo> eoOptional = userFansRepository
                .oneOptByUserIdAndFollowUserId(UserContext.getUserId(), addVo.getFollowUserId());
        eoOptional.ifPresentOrElse(userFansEo -> {
            if (StatusEnum.VALID.equalsIntVal(userFansEo.getStatus())) {
                //取消关注
                userFansEo.setStatus(StatusEnum.INVALID.getIntVal());
                userRepository.updateById(userEo.setFansCount(userEo.getFansCount() - 1));
            } else {
                userFansEo.setStatus(StatusEnum.VALID.getIntVal());
                userRepository.updateById(userEo.setFansCount(userEo.getFansCount() + 1));
            }
            userFansEo.setType(addVo.getType());
            userFansRepository.updateById(userFansEo);
        }, () -> {
            final UserFansEo fansEo = UserFansEo.builder().followUserId(addVo.getFollowUserId())
                    .userId(UserContext.getUserId())
                    .type(addVo.getType()).status(StatusEnum.VALID.getIntVal()).build();
            userFansRepository.save(fansEo);
            userRepository.updateById(userEo.setFansCount(userEo.getFansCount() + 1));
        });
    }

    @Override
    public UserFansDetailVo getUserFans(Long followUserId) {
        final UserInfoContext currentUser = userContextHolder.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            return UserFansDetailVo.builder().followUserId(followUserId).status(StatusEnum.INVALID.getIntVal())
                    .build();
        }
        final Optional<UserFansEo> eoOptional = userFansRepository.oneOptByUserIdAndFollowUserId(currentUser.getId(), followUserId);
        if (eoOptional.isEmpty()) {
            return UserFansDetailVo.builder().followUserId(followUserId).status(StatusEnum.INVALID.getIntVal())
                    .userId(currentUser.getId()).build();
        }
        return SmartBeanCopy.copy(eoOptional.get(), UserFansDetailVo.class);
    }

    @Override
    public Page<UserFansVo> pageFollowByVo(UserFansQueryVo queryVo) {
        return userFansRepository.getMapper()
                .listFollowPage(Page.of(queryVo.getPage(), queryVo.getPageSize()), queryVo);
    }

    @Override
    public Page<UserFansVo> pageByVo(UserFansQueryVo queryVo) {
        return userFansRepository.getMapper()
                .listFansPage(Page.of(queryVo.getPage(), queryVo.getPageSize()), queryVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(UserFansVo userFansVo) {
        final UserEo userEo = userRepository.getById(userFansVo.getFollowUserId());
        AssertUtils.isNotNull(userEo, "userEo invalid");
        final Optional<UserFansEo> optional = userFansRepository.lambdaQuery()
                .eq(UserFansEo::getUserId, userFansVo.getUserId())
                .eq(UserFansEo::getFollowUserId, userFansVo.getFollowUserId())
                .eq(UserFansEo::getStatus, StatusEnum.VALID.getIntVal()).oneOpt();
        optional.ifPresent(userFansEo -> {
            userFansEo.setStatus(StatusEnum.INVALID.getIntVal());
            userFansRepository.updateById(userFansEo);
            userRepository.updateById(userEo.setFansCount(userEo.getFansCount() - 1));
        });
    }
}
